package com.bgds.sys.module.controller;


import com.alibaba.fastjson.JSONObject;
import com.bgds.sys.common.pagevo.ElectricMotorVo;
import com.bgds.sys.common.pagevo.Result;
import com.bgds.sys.common.pagevo.SectionVo;
import com.bgds.sys.common.pagevo.SeriesVo;
import com.bgds.sys.common.utils.DateUtils;
import com.bgds.sys.common.utils.ResultUtil;
import com.bgds.sys.influx.service.InfluxService;
import com.bgds.sys.module.entity.Device;
import com.bgds.sys.module.entity.DeviceDynamicAttr;
import com.bgds.sys.module.entity.DeviceStaticAttr;
import com.bgds.sys.module.entity.dto.AlarmLogDto;
import com.bgds.sys.module.service.IAlarmLogService;
import com.bgds.sys.module.service.IDeviceDynamicAttrService;
import com.bgds.sys.module.service.IDeviceService;
import com.bgds.sys.module.service.IDeviceStaticAttrService;
import com.bgds.sys.task.CronSchedulerJob;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.charts.ChartData;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import sun.misc.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lj
 */
@Slf4j
@RestController
@Api(tags = "辊道电机监测接口")
@RequestMapping("/roller")
public class RollerController {

    @Autowired
    private IDeviceDynamicAttrService iDeviceDynamicAttrService;
    @Autowired
    private InfluxService influxService;
    @Autowired
    private IAlarmLogService iAlarmLogService;
    @Autowired
    private IDeviceStaticAttrService deviceStaticAttrService;


    @RequestMapping(value = "/getRollerData", method = RequestMethod.GET)
    @ApiOperation(value = "辊道段监测监测数据", notes = "辊道段监测监测数据", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deviceCode", dataType = "String", required = true, value = "设备编号(code)"),
            @ApiImplicitParam(name = "startTime", value = "起始时间"),
            @ApiImplicitParam(name = "endTime", value = "结束时间"),
    })

    public Result<Map<String, Object>> getRollerData(String deviceCode, Long startTime, Long endTime) {
        Map<String, Object> map = new HashMap<>(10);
        List<DeviceDynamicAttr> deviceDynamicAttrs = iDeviceDynamicAttrService.listByDeviceCode(deviceCode, null);
        //设备报警日志
        List<AlarmLogDto> alarmLogs = iAlarmLogService.listByParam(deviceCode, startTime, endTime);
        Map<String, List<DeviceDynamicAttr>> groupMap = deviceDynamicAttrs.stream()
                //过滤辊道状态
                .filter(e -> !"state".equals(e.getEngName()))
                .filter(dda -> StringUtils.isNotBlank(dda.getFilterCode()))
                .collect(
                        Collectors.groupingBy((DeviceDynamicAttr dda) -> dda.getFilterCode())
                );
        Map<String, Object> chartObject = new HashMap<>(10);
        groupMap.forEach((filterCode, dynamicAttrs) -> {
            List<SeriesVo> chartData;
            if (filterCode.equals("curr")) {
                //辊轮分组
                Map<String, List<DeviceDynamicAttr>> mapWheel = dynamicAttrs.stream().filter(dda -> StringUtils.isNotBlank(dda.getGroupCode())).collect(Collectors.groupingBy(DeviceDynamicAttr::getGroupCode, LinkedHashMap::new, Collectors.toList()));
                List<List<SeriesVo>> chartDataList = new ArrayList<>();
                for (Map.Entry<String, List<DeviceDynamicAttr>> entry : mapWheel.entrySet()) {
                    List<DeviceDynamicAttr> mapValue = entry.getValue();
                    chartData = influxService.queryByForMap(deviceCode, startTime, endTime, mapValue);
                    if (chartData.size() == 0) {
                        chartData = createSeriesVo(startTime, endTime, mapValue);
                    }
                    chartDataList.add(chartData);
                }
                chartObject.put("curr", chartDataList);
            } else if (filterCode.equals("speed_elect")) {
                //获取默认值
                List<DeviceStaticAttr> deviceStaticAttrs = deviceStaticAttrService.getStaticAttByDeviceCode(deviceCode);
                dynamicAttrs = dynamicAttrs.stream().filter(item -> !(item.getName().contains("转速") && item.getName().contains("额定"))).collect(Collectors.toList());
                ;
                //图表数据
                chartData = influxService.queryByForMap(deviceCode, startTime, endTime, dynamicAttrs);
                if (chartData.size() == 0) {
                    chartData = createSeriesVo(startTime, endTime, dynamicAttrs);
                }
                for (SeriesVo seriesVo : chartData) {
                    Optional<DeviceStaticAttr> dsa = deviceStaticAttrs.stream().filter(x -> x.getName().equals(seriesVo.getEngName())).findFirst();
                    if (dsa.isPresent()) {
                        seriesVo.setValue(Double.valueOf(dsa.get().getValue()));
                    }
                }
                chartObject.put(filterCode, chartData);
            }

        });
        map.put("chartList", chartObject);
        map.put("alarmLogs", alarmLogs);

        return new ResultUtil<Map<String, Object>>().setData(map);
    }


    private List<SeriesVo> createSeriesVo(Long startTime, Long endTime, List<DeviceDynamicAttr> deviceDynamicAttrs) {
        List<SeriesVo> seriesVos = new ArrayList<>();
        List<Long> millis = DateUtils.getIntervalTimeList(new Date(startTime), new Date(endTime), 5000 * 6);
        //稀释
        if (millis.size() > 2000) {
            List<Long> dilutionMillis = new ArrayList<>();
            int interval = (int) Math.ceil((float) millis.size() / 2000);
            for (int i = 0; i < millis.size(); i = i + interval) {
                dilutionMillis.add(millis.get(i));
            }
            for (Long l : dilutionMillis) {
                for (DeviceDynamicAttr ddc : deviceDynamicAttrs) {
                    SeriesVo sv = new SeriesVo();
                    sv.setValue(0.0);
                    sv.setName(ddc.getName());
                    sv.setTime(l);
                    sv.setEngName(ddc.getEngName());
                    seriesVos.add(sv);
                }
            }
        } else {
            for (Long l : millis) {
                for (DeviceDynamicAttr ddc : deviceDynamicAttrs) {
                    SeriesVo sv = new SeriesVo();
                    sv.setValue(0.0);
                    sv.setName(ddc.getName());
                    sv.setTime(l);
                    sv.setEngName(ddc.getEngName());
                    seriesVos.add(sv);
                }
            }
        }
        return seriesVos;
    }
}
